/*
 * 
 */
package org.opu.translator;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *  Parser of string
 * @author yura
 */
public class RETokenizer {

    /** rules on who are looking for tokens */
    private List<Rule> rules;

    RETokenizer(){
        rules = null;
    }

    /**
     *  parses the string and finds her tokens to set rules
     * @param rules rules on who are looking for tokens
     */
    public RETokenizer(List<Rule> rules) {
        this.rules = rules;
    }

    /**
     *  parses the string and finds her tokens to set rules
     * @param source parsesed string
     * @return list of detected tokens
     */
    public List<Token> tokenize (String source) {
        return tokenize(source, rules);
    }


    /**
     *  parses the string and finds her tokens to set rules
     * @param source parsesed string
     * @param rules rules on who are looking for tokens
     * @return list of detected tokens 
     */
    //static //it`s can be static, because dont use class resurses
    List<Token> tokenize (String source, List<Rule> rules) {
        //create variables
        List<Token> tokens = new ArrayList<Token>();
        int pos = 0;
        final int end = source.length();
        
        //init variable of scaning
        Matcher m = Pattern.compile("dummy")
                .matcher(source)
                .useTransparentBounds(true)
                .useAnchoringBounds(false);
        
        //main loop of scaning
        while (pos < end) {
            m.region(pos, end);
            boolean b = true;
            
            //do check for all rules
            for (Rule r : rules) {
                if (m.usePattern(r.pattern).lookingAt()) {
                    tokens.add(new Token(r.name, m.start(), m.end()));
                    pos = m.end();
                    b = false;
                    break;
                }
            }

            if (b) {// bump-along, in case no rule matched
                pos++;
            }
       }

        return tokens;
    }
}
